package studio.baka.satoripixeldungeon.items.artifacts;

import studio.baka.satoripixeldungeon.Assets;
import studio.baka.satoripixeldungeon.Dungeon;
import studio.baka.satoripixeldungeon.actors.buffs.Buff;
import studio.baka.satoripixeldungeon.actors.buffs.Roots;
import studio.baka.satoripixeldungeon.actors.hero.Hero;
import studio.baka.satoripixeldungeon.effects.CellEmitter;
import studio.baka.satoripixeldungeon.effects.particles.EarthParticle;
import studio.baka.satoripixeldungeon.items.Item;
import studio.baka.satoripixeldungeon.messages.Messages;
import studio.baka.satoripixeldungeon.plants.Earthroot;
import studio.baka.satoripixeldungeon.plants.Plant;
import studio.baka.satoripixeldungeon.scenes.GameScene;
import studio.baka.satoripixeldungeon.sprites.ItemSpriteSheet;
import studio.baka.satoripixeldungeon.utils.GLog;
import studio.baka.satoripixeldungeon.windows.WndBag;
import com.watabou.noosa.Camera;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Bundle;

import java.util.ArrayList;
import java.util.Collections;

@SuppressWarnings("rawtypes")
public class SandalsOfNature extends Artifact {

    {
        image = ItemSpriteSheet.ARTIFACT_SANDALS;

        levelCap = 3;

        charge = 0;

        defaultAction = AC_ROOT;
    }

    public static final String AC_FEED = "FEED";
    public static final String AC_ROOT = "ROOT";

    protected WndBag.Mode mode = WndBag.Mode.SEED;

    public ArrayList<Class> seeds = new ArrayList<>();

    @Override
    public ArrayList<String> actions(Hero hero) {
        ArrayList<String> actions = super.actions(hero);
        if (isEquipped(hero) && level() < 3 && !cursed)
            actions.add(AC_FEED);
        if (isEquipped(hero) && charge > 0)
            actions.add(AC_ROOT);
        return actions;
    }

    @Override
    public void execute(Hero hero, String action) {
        super.execute(hero, action);

        if (action.equals(AC_FEED)) {

            GameScene.selectItem(itemSelector, mode, Messages.get(this, "prompt"));

        } else if (action.equals(AC_ROOT) && level() > 0) {

            if (!isEquipped(hero)) GLog.i(Messages.get(Artifact.class, "need_to_equip"));
            else if (charge == 0) GLog.i(Messages.get(this, "no_charge"));
            else {
                Buff.prolong(hero, Roots.class, 5);
                Buff.affect(hero, Earthroot.Armor.class).level(charge);
                CellEmitter.bottom(hero.pos).start(EarthParticle.FACTORY, 0.05f, 8);
                Camera.main.shake(1, 0.4f);
                charge = 0;
                updateQuickslot();
            }
        }
    }

    @Override
    protected ArtifactBuff passiveBuff() {
        return new Naturalism();
    }

    @Override
    public void charge(Hero target) {
        target.buff(Naturalism.class).charge();
    }

    @Override
    public String desc() {
        String desc = Messages.get(this, "desc_" + (level() + 1));

        if (isEquipped(Dungeon.hero)) {
            desc += "\n\n";

            if (!cursed)
                desc += Messages.get(this, "desc_hint");
            else
                desc += Messages.get(this, "desc_cursed");

            if (level() > 0)
                desc += "\n\n" + Messages.get(this, "desc_ability");
        }

        if (!seeds.isEmpty()) {
            desc += "\n\n" + Messages.get(this, "desc_seeds", seeds.size());
        }

        return desc;
    }

    @Override
    public Item upgrade() {
        if (level() < 0) image = ItemSpriteSheet.ARTIFACT_SANDALS;
        else if (level() == 0) image = ItemSpriteSheet.ARTIFACT_SHOES;
        else if (level() == 1) image = ItemSpriteSheet.ARTIFACT_BOOTS;
        else if (level() >= 2) image = ItemSpriteSheet.ARTIFACT_GREAVES;
        name = Messages.get(this, "name_" + (level() + 1));
        return super.upgrade();
    }


    private static final String SEEDS = "seeds";

    @Override
    public void storeInBundle(Bundle bundle) {
        super.storeInBundle(bundle);
        bundle.put(SEEDS, seeds.toArray(new Class[0]));
    }

    @Override
    public void restoreFromBundle(Bundle bundle) {
        super.restoreFromBundle(bundle);
        if (level() > 0) name = Messages.get(this, "name_" + level());
        if (bundle.contains(SEEDS))
            Collections.addAll(seeds, bundle.getClassArray(SEEDS));
        if (level() == 1) image = ItemSpriteSheet.ARTIFACT_SHOES;
        else if (level() == 2) image = ItemSpriteSheet.ARTIFACT_BOOTS;
        else if (level() >= 3) image = ItemSpriteSheet.ARTIFACT_GREAVES;
    }

    public class Naturalism extends ArtifactBuff {
        public void charge() {
            if (level() > 0 && charge < target.HT) {
                //gain 1+(1*level)% of the difference between current charge and max HP.
                charge += (Math.round((target.HT - charge) * (.01 + level() * 0.01)));
                updateQuickslot();
            }
        }
    }

    protected WndBag.Listener itemSelector = item -> {
        if (item instanceof Plant.Seed) {
            if (seeds.contains(item.getClass())) {
                GLog.w(Messages.get(SandalsOfNature.class, "already_fed"));
            } else {
                seeds.add(item.getClass());

                Hero hero = Dungeon.hero;
                hero.sprite.operate(hero.pos);
                Sample.INSTANCE.play(Assets.SND_PLANT);
                hero.busy();
                hero.spend(2f);
                if (seeds.size() >= 3 + (level() * 3)) {
                    seeds.clear();
                    upgrade();
                    if (level() >= 1 && level() <= 3) {
                        GLog.p(Messages.get(SandalsOfNature.class, "levelup"));
                    }

                } else {
                    GLog.i(Messages.get(SandalsOfNature.class, "absorb_seed"));
                }
                item.detach(hero.belongings.backpack);
            }
        }
    };

}
